//package com.songqi.common.core.annotation;//package com.songqi.common.core.annotation;
//
//
//import com.songqi.common.core.domain.R;
//import net.jodah.expiringmap.ExpirationPolicy;
//import net.jodah.expiringmap.ExpiringMap;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.springframework.stereotype.Component;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.servlet.http.HttpServletRequest;
//import java.util.concurrent.ConcurrentHashMap;
//import java.util.concurrent.TimeUnit;
//
///**
// * 自定义切面判定访问频率
// *
// * @author zhangrui
// * @date 2021年10月30日 16:22
// */
//@Aspect
//@Component
//public class RequestLimitAspect {
//
//    /**
//     * 登记 book<String, ExpiringMap>
//     * key -> 请求路径URI
//     * value -> ExpiringMap<String, Integer>
//     *          key -> 请求地址URL
//     *          value -> 请求次数
//     * */
//    private static ConcurrentHashMap<String, ExpiringMap> book = new ConcurrentHashMap<>();
//
//    /**
//     * 定义切点
//     * 让所有标注@LimitRequest注解的方法都执行切面方法
//     * @param requestLimit
//     */
//    @Pointcut("@annotation(requestLimit)")
//    public void executeService(RequestLimit requestLimit) {
//
//    }
//
//    /**
//     *
//     * @param proceedingJoinPoint
//     * @param requestLimit
//     * @return
//     * @throws Throwable
//     */
//    @Around("excudeService(requestLimit)")
//    public R doAround(ProceedingJoinPoint proceedingJoinPoint, RequestLimit requestLimit) throws Throwable {
//        // 获得request对象
//        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = servletRequestAttributes.getRequest();
//        // 获取Map对象，如果没有则返回默认值，第一个参数是key，第二个参数是默认值
//        ExpiringMap<String, Integer> expiringMap = book.getOrDefault(request.getRequestURI(), ExpiringMap.builder().variableExpiration().build());
//        Integer requestCount = expiringMap.getOrDefault(request.getRemoteAddr(), 0);
//        // 如果请求超过次数，不执行目标方法
//        if (requestCount >= requestLimit.count()) {
//            return R.fail("请不要重复请求");
//        } else if (requestCount == 0) {
//            // 第一次请求时，设置有效时间
//            expiringMap.put(request.getRemoteAddr(), requestCount + 1, ExpirationPolicy.CREATED, requestLimit.time(),
//                    TimeUnit.MILLISECONDS);
//        } else {
//            // 未超过请求次数，记录+1
//            expiringMap.put(request.getRemoteAddr(), requestCount + 1);
//        }
//        book.put(request.getRequestURI(), expiringMap);
//        // result的值就是被拦截方法的返回值
//        R result = (R)proceedingJoinPoint.proceed();
//        return result;
//    }
//}
